﻿using System;
using System.Collections.Generic;
using System.Web.Http;
using Models.Requests;
using Models.Responses;
using System.Data.SqlClient;
using DataAccess;
using WebApi.Classes;
using System.Data;
using System.Web.Mvc;
using System.Web.UI;
using Newtonsoft.Json;
using Models.Models;
using System.IO;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net;
using PdfSharp.Pdf;
using PdfSharp.Drawing;

namespace WebApi.Controllers
{
    public class ReportController : ApiController
    {
        [System.Web.Http.AllowAnonymous]
        [System.Web.Http.HttpGet]
        [OutputCache(Duration = 1, VaryByParam = "none", Location = OutputCacheLocation.Any)]
        public DashboardSetResponse GetUserStoreStatistics(string parameter)
        {
            var request = (DashboardSetRequest)JsonConvert.DeserializeObject(parameter, typeof(DashboardSetRequest));

            DashboardSetResponse response = new DashboardSetResponse() { BarLineChartSetList = new List<BarLineChartSet>(), PieChartSetList = new List<PieChartSet>() };

            try
            {
                var result = GetUserStoreStatisticsData(request);

                Statics.FetchDebugParameters((BaseResponse)response, result);

                response.GraphTitle = result.Parameters["szGraphTitle"].Value.ToString();
                response.GraphType = result.Parameters["iGraphTypeID"].Value.ToString();

                if (result.DataSet != null && result.DataSet.Tables.Count > 0)
                {
                    foreach (DataRow row in result.DataSet.Tables[0].Rows)
                    {
                        response.BarLineChartSetList.Add(new BarLineChartSet()
                        {
                            DomainID = Convert.ToInt64(row["StoreIPListID"]),
                            StoreID = Convert.ToInt64(row["StoreID"]),
                            NumberOrdsNoPopUp = Convert.ToInt64(row["NumberOrdsNoPopUp"]),
                            NumberOrdsWithPopUp = Convert.ToInt64(row["NumberOrdsWithPopUp"]),
                            NumberPopUps = Convert.ToInt64(row["NumberPopUps"]),
                            NumberSessions = Convert.ToInt64(row["NumberSessions"]),
                            XAxisValue = row["XAxisValue"].ToString(),
                            XAxis = row["XAxis"].ToString(),
                            YAxis = row["YAxis"].ToString(),
                            Year = Convert.ToInt32(row["Year"]),
                        });
                    }

                    foreach (DataRow row in result.DataSet.Tables[1].Rows)
                    {
                        response.PieChartSetList.Add(new PieChartSet()
                        {
                            DomainID = Convert.ToInt64(row["StoreIPListID"]),
                            StoreID = Convert.ToInt64(row["StoreID"]),
                            NumberPopUps = Convert.ToInt64(row["NumberPopUps"]),
                            NumberOrdersWithPopUps = Convert.ToInt64(row["NumberOrdersWithPopUps"]),
                            NumberSessions = Convert.ToInt64(row["NumberSessions"]),
                            YAxis = row["YAxis"].ToString(),
                            Coupon = row["eCommCouponID"].ToString()
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                response.Exception = ex;
            }

            return response;
        }
        
        [System.Web.Http.AllowAnonymous]
        [System.Web.Http.HttpGet]
        public HttpResponseMessage InvoicePDF(long id, long ppjStoreID, long storeID, long userID)
        {
            var invoice = new InvoiceController().GetInvoice(new InvoiceRequest(userID, new Invoice() { ID = id })).Invoice;
            var store = new StoreController().GetStore(new StoreRequest(new Store() { ID = storeID })).Store;
            var storePPJ = new StoreController().GetStore(new StoreRequest(new Store() { ID = ppjStoreID })).Store;
            
            PdfDocument document = new PdfDocument();
            document.Info.Title = "Invoice # " + id;
            document.Info.Author = "PopUpJoe";

            // Create new page
            PdfPage page = document.AddPage();

            // Get an XGraphics object for drawing
            XGraphics gfx = XGraphics.FromPdfPage(page);

            XFont f_large = new XFont("Verdana", 14, XFontStyle.Bold);
            XFont f_norm = new XFont("Verdana", 10, XFontStyle.Regular);
            XFont fb_norm = new XFont("Verdana", 10, XFontStyle.Bold);
            
            gfx.DrawString("PopUpJoe", f_large, XBrushes.Black, 20, 40);
            gfx.DrawString(string.Format("INVOICE # {0}", id), f_large, XBrushes.Black, 450, 40);

            gfx.DrawString(string.Format("{0} {1}", storePPJ.Address1, storePPJ.Address2), f_norm, XBrushes.Black, 20, 80);
            gfx.DrawString(string.Format("{0}, {1} {2}", storePPJ.City, storePPJ.StateProvince, storePPJ.PostalCode), f_norm, XBrushes.Black, 20, 100);
            
            gfx.DrawString("Billing Date:", fb_norm, XBrushes.Black, 350, 80);
            gfx.DrawString(invoice.BillingDate.ToString("MM/dd/yyyy"), f_norm, XBrushes.Black, 440, 80);
            gfx.DrawString("Billing Period:", fb_norm, XBrushes.Black, 350, 100);
            gfx.DrawString(invoice.BillingPeriodName, f_norm, XBrushes.Black, 440, 100);
            gfx.DrawString("Billing Type:", fb_norm, XBrushes.Black, 350, 120);
            gfx.DrawString(invoice.BillingTypeName, f_norm, XBrushes.Black, 440, 120);
            gfx.DrawString("Domain:", fb_norm, XBrushes.Black, 350, 140);
            gfx.DrawString(invoice.DomainName, f_norm, XBrushes.Black, 440, 140);

            gfx.DrawString("TO:", fb_norm, XBrushes.Black, 20, 200);

            gfx.DrawString(store.Name, f_norm, XBrushes.Black, 20, 220);
            gfx.DrawString(string.Format("{0} {1}", store.Address1, store.Address2), f_norm, XBrushes.Black, 20, 240);
            gfx.DrawString(string.Format("{0}, {1} {2}", store.City, store.StateProvince, store.PostalCode), f_norm, XBrushes.Black, 20, 260);
            gfx.DrawString("Please complete payment for the following services within 30 days of above date.", f_norm, XBrushes.Black, 20, 340);

            gfx.DrawString("From", fb_norm, XBrushes.Black, 20, 400);
            gfx.DrawString("To", fb_norm, XBrushes.Black, 100, 400);
            gfx.DrawString("Description", fb_norm, XBrushes.Black, 180, 400);
            gfx.DrawString("Billing Rate", fb_norm, XBrushes.Black, 420, 400);
            gfx.DrawString("Total", fb_norm, XBrushes.Black, 520, 400);

            gfx.DrawString(invoice.From.ToString("MM/dd/yyyy"), f_norm, XBrushes.Black, 20, 420);
            gfx.DrawString(invoice.To.ToString("MM/dd/yyyy"), f_norm, XBrushes.Black, 100, 420);
            gfx.DrawString(string.Format("{0} {1}", invoice.NumberOfUnits.ToString("###,###,###"), invoice.NameOfUnit), f_norm, XBrushes.Black, 180, 420);
            gfx.DrawString(invoice.BillingRate.ToString("###,###.0000"), f_norm, XBrushes.Black, 420, 420);
            gfx.DrawString(invoice.Total.ToString("###,###,###.00"), f_norm, XBrushes.Black, 520, 420);

            gfx.DrawString("THANK YOU FOR YOUR BUSINESS!", fb_norm, XBrushes.Black, 20, 600);

            MemoryStream output = new MemoryStream();

            document.Save(output, false);

            var sr = new StreamReader(output);
            string sb = sr.ReadToEnd();

            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            result.Content = new StringContent(sb);

            //a text file is actually an octet-stream (pdf, etc)
            result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

            //we used attachment to force download
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
            result.Content.Headers.ContentDisposition.FileName = "invoice_" + id + ".pdf";

            return result;
        }
        

        [System.Web.Http.AllowAnonymous]
        [System.Web.Http.HttpGet]
        public HttpResponseMessage InvoiceDetailsCSV(long id, long userID)
        {
            var response = new InvoiceController().GetInvoiceDetails(new InvoiceRequest(userID, new Invoice() { ID = id }));

            StringBuilder sb = new StringBuilder();
            MemoryStream output = new MemoryStream();

            if (response.InvoiceList.List.Count > 0)
            {
                var columnLine = string.Empty;

                foreach (var prop in typeof(Invoice).GetProperties())
                {
                    columnLine += prop.Name + ", ";
                }

                sb.AppendLine(columnLine);

                foreach (var invoice in response.InvoiceList.List)
                {
                    var newLine = string.Empty;

                    foreach (var prop in typeof(Invoice).GetProperties())
                    {
                        newLine += string.Format("{0}, ", prop.GetValue(invoice, null) == null ? string.Empty : prop.GetValue(invoice, null).ToString());
                    }

                    sb.AppendLine(newLine);
                }
            }

            using (StreamWriter sw = new StreamWriter(output, Encoding.Unicode))
            {
                sw.Write(sb.ToString());
            }

            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            result.Content = new StringContent(sb.ToString());

            //a text file is actually an octet-stream (pdf, etc)
            result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");

            //we used attachment to force download
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
            result.Content.Headers.ContentDisposition.FileName = "invoice_" + id + ".csv";

            return result;
        }

        [System.Web.Http.AllowAnonymous]
        [System.Web.Http.HttpGet]
        [OutputCache(Duration = 1, VaryByParam = "none", Location = OutputCacheLocation.Any)]
        public HttpResponseMessage GetUserStoreStatisticsCSV(string parameter)
        {
            var request = (DashboardSetRequest)JsonConvert.DeserializeObject(parameter, typeof(DashboardSetRequest));

            StringBuilder sb = new StringBuilder();
            MemoryStream output = new MemoryStream();

            try
            {
                var data = GetUserStoreStatisticsData(request);

                if (data.DataSet != null && data.DataSet.Tables.Count > 0)
                {
                    var columnLine = string.Empty;

                    foreach (DataColumn column in data.DataSet.Tables[0].Columns)
                    {
                        columnLine += column.ColumnName + ", ";
                    }

                    sb.AppendLine(columnLine);

                    foreach (DataRow row in data.DataSet.Tables[0].Rows)
                    {
                        var newLine = string.Empty;

                        foreach (DataColumn column in data.DataSet.Tables[0].Columns)
                        {
                            newLine += string.Format("{0}, ", row[column.ColumnName].ToString());
                        }

                        sb.AppendLine(newLine);
                    }
                }

                using (StreamWriter sw = new StreamWriter(output, Encoding.Unicode))
                {
                    sw.Write(sb.ToString());
                }
            }
            catch (Exception ex)
            {

            }

            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            result.Content = new StringContent(sb.ToString());
            
            //a text file is actually an octet-stream (pdf, etc)
            result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
            
            //we used attachment to force download
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
            result.Content.Headers.ContentDisposition.FileName = "dashboard.csv";
            
            return result;
        }

        private Result GetUserStoreStatisticsData(DashboardSetRequest request)
        {
            List<SqlParameter> parameters = new List<SqlParameter>();
            parameters.Add(new SqlParameter("biUserID", request.UserID));

            Statics.AddDebugParameters(parameters);

            if (request.Start.HasValue)
            {
                parameters.Add(new SqlParameter("dtStart", new DateTime(request.Start.Value.Year, request.Start.Value.Month, request.Start.Value.Day, 12, 00, 00)));
            }

            if (request.End.HasValue)
            {
                parameters.Add(new SqlParameter("dtEnd", new DateTime(request.End.Value.Year, request.End.Value.Month, request.End.Value.Day, 23, 59, 59)));
            }

            if (request.GroupTypeID.HasValue)
            {
                parameters.Add(new SqlParameter("iGroupTypeID", request.GroupTypeID));
            }

            if (request.StoreID.HasValue)
            {
                parameters.Add(new SqlParameter("biStoreID", request.StoreID));
            }

            if (request.DomainID.HasValue)
            {
                parameters.Add(new SqlParameter("biStoreIPListID", request.DomainID));
            }

            if (request.HideRevoked.HasValue)
            {
                parameters.Add(new SqlParameter("bHideRevoked", request.HideRevoked));
            }

            parameters.Add(new SqlParameter("szGraphTitle", string.Empty) { Direction = System.Data.ParameterDirection.Output, Size = 2048 });
            parameters.Add(new SqlParameter("iGraphTypeID", 0) { Direction = System.Data.ParameterDirection.Output });

            var result = new DataSource().ExecuteDataSet("svc.uspGetDashboardSet", parameters);

            return result;
        }
    }
}
